package thomp.robots;

import battlecode.common.*;
import java.util.ArrayList;

/**
 * Archon robot class.
 *
 * @author jthompson
 */
public class Archon extends RobotBase {

    /**
     * Keep track of who needs flux.
     */
    public static ArrayList<Robot> m_BotsNeedingFlux = new ArrayList<Robot>();

    /**
     * Constructor
     *
     * @param myRC Passed in from BattleCode server.
     */
    public Archon(RobotController myRC) {
        super(myRC);
    }

    /**
     * Primary action loop.
     */
    public void run() {
        try {
            // Locate any nearby units needing Flux.
            this.SenseRobotsNeedingFlux();

            // Refuel anything within range
            for (Robot bot : this.m_BotsNeedingFlux) {
                this.TransferFlux(bot);
            }
            this.m_BotsNeedingFlux.clear();

            this.SpawnIfPossible(RobotType.SOLDIER);

            this.attack();
            this.wander();
        } catch (Exception e) {
            System.out.println("caught exception:");
            e.printStackTrace();
        }
    }

    /**
     * Spawn a robot of the specified type.
     *
     * @param type Type of robot to spawn.
     * @return TRUE if successful, FALSE otherwise.
     */
    private boolean SpawnIfPossible(RobotType type) {
        try {

            if ((myRC.getFlux() > type.spawnCost)
                    && (!myRC.isMovementActive())
                    && (myRC.canMove(myRC.getDirection()))) {
                myRC.spawn(type);
                return true;
            } else {
                return false;
            }

        } catch (Exception e) {
            System.out.println("caught exception:");
            e.printStackTrace();
            return false;
        }
    }

    /**
     * Sense robots in the area that need flux.
     */
    private void SenseRobotsNeedingFlux() {
        try {
            Robot[] bots = myRC.senseNearbyGameObjects(Robot.class);
            for (Robot bot : bots) {
                RobotInfo rInfo = myRC.senseRobotInfo(bot);
                if ((rInfo.team == myRC.getTeam())
                        && (rInfo.flux <= MIN_FLUX)
                        && (rInfo.type != RobotType.ARCHON)) {
                    this.m_BotsNeedingFlux.add(bot);
                }
            }
        } catch (Exception e) {
            System.out.println("caught exception:");
            e.printStackTrace();
        }
    }

    private void TransferFlux(Robot bot) {
        try {
            
            // Check range          
            int distance = myRC.getLocation().distanceSquaredTo(myRC.senseLocationOf(bot));           
            if (distance != 1)
                return;
            
            // Make the transfer            
            myRC.transferFlux(
                    myRC.senseLocationOf(bot),
                    bot.getRobotLevel(),
                    myRC.getFlux() / 2.0d);
            
        } catch (Exception e) {
            System.out.println("caught exception:");
            e.printStackTrace();
        }
    }
}
